package org.jsola.contract.query;

import io.swagger.annotations.ApiParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import org.jsola.contract.constant.ContractType;
import org.jsola.contract.constant.FileType;
import org.jsola.contract.constant.SealType;
import org.jsola.core.query.BaseQuery;
import org.jsola.orm.filter.Order;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import static org.jsola.contract.example.ContractExample.E_AGAIN_CONTRACT_ID;
import static org.jsola.contract.example.ContractExample.E_APP_IS_SHOW;
import static org.jsola.contract.example.ContractExample.E_CATEGORY_ID;
import static org.jsola.contract.example.ContractExample.E_CONTENT;
import static org.jsola.contract.example.ContractExample.E_CONTRACT_NO;
import static org.jsola.contract.example.ContractExample.E_CONTRACT_TYPE;
import static org.jsola.contract.example.ContractExample.E_DATELINE;
import static org.jsola.contract.example.ContractExample.E_EMP_SIGN_DATE_END;
import static org.jsola.contract.example.ContractExample.E_EMP_SIGN_DATE_START;
import static org.jsola.contract.example.ContractExample.E_END_DATE_END;
import static org.jsola.contract.example.ContractExample.E_END_DATE_START;
import static org.jsola.contract.example.ContractExample.E_FILE_TYPE;
import static org.jsola.contract.example.ContractExample.E_IS_CHECK_FACE;
import static org.jsola.contract.example.ContractExample.E_NAME;
import static org.jsola.contract.example.ContractExample.E_NEED_INIT_AGAIN;
import static org.jsola.contract.example.ContractExample.E_PARTY_A_ACCOUNT_ID;
import static org.jsola.contract.example.ContractExample.E_PARTY_A_NAME;
import static org.jsola.contract.example.ContractExample.E_PARTY_B_ACCOUNT_ID;
import static org.jsola.contract.example.ContractExample.E_PARTY_B_NAME;
import static org.jsola.contract.example.ContractExample.E_PRICE;
import static org.jsola.contract.example.ContractExample.E_PUBLISH_DATE_END;
import static org.jsola.contract.example.ContractExample.E_PUBLISH_DATE_START;
import static org.jsola.contract.example.ContractExample.E_SEAL_TYPE;
import static org.jsola.contract.example.ContractExample.E_SIGN_DATE_END;
import static org.jsola.contract.example.ContractExample.E_SIGN_DATE_START;
import static org.jsola.contract.example.ContractExample.E_SIGN_FINISH_DATE_END;
import static org.jsola.contract.example.ContractExample.E_SIGN_FINISH_DATE_START;
import static org.jsola.contract.example.ContractExample.E_SIGN_NO;
import static org.jsola.contract.example.ContractExample.E_STATUS;
import static org.jsola.contract.example.ContractExample.E_SUBJECT_ID;
import static org.jsola.contract.example.ContractExample.E_TEMPLATE_ID;
import static org.jsola.contract.example.ContractExample.N_AGAIN_CONTRACT_ID;
import static org.jsola.contract.example.ContractExample.N_APP_IS_SHOW;
import static org.jsola.contract.example.ContractExample.N_CATEGORY_ID;
import static org.jsola.contract.example.ContractExample.N_CONTENT;
import static org.jsola.contract.example.ContractExample.N_CONTRACT_NO;
import static org.jsola.contract.example.ContractExample.N_CONTRACT_TYPE;
import static org.jsola.contract.example.ContractExample.N_DATELINE;
import static org.jsola.contract.example.ContractExample.N_EMP_SIGN_DATE_END;
import static org.jsola.contract.example.ContractExample.N_EMP_SIGN_DATE_START;
import static org.jsola.contract.example.ContractExample.N_END_DATE_END;
import static org.jsola.contract.example.ContractExample.N_END_DATE_START;
import static org.jsola.contract.example.ContractExample.N_FILE_TYPE;
import static org.jsola.contract.example.ContractExample.N_IS_CHECK_FACE;
import static org.jsola.contract.example.ContractExample.N_NAME;
import static org.jsola.contract.example.ContractExample.N_NEED_INIT_AGAIN;
import static org.jsola.contract.example.ContractExample.N_PARTY_A_ACCOUNT_ID;
import static org.jsola.contract.example.ContractExample.N_PARTY_A_NAME;
import static org.jsola.contract.example.ContractExample.N_PARTY_B_ACCOUNT_ID;
import static org.jsola.contract.example.ContractExample.N_PARTY_B_NAME;
import static org.jsola.contract.example.ContractExample.N_PRICE;
import static org.jsola.contract.example.ContractExample.N_PUBLISH_DATE_END;
import static org.jsola.contract.example.ContractExample.N_PUBLISH_DATE_START;
import static org.jsola.contract.example.ContractExample.N_SEAL_TYPE;
import static org.jsola.contract.example.ContractExample.N_SIGN_DATE_END;
import static org.jsola.contract.example.ContractExample.N_SIGN_DATE_START;
import static org.jsola.contract.example.ContractExample.N_SIGN_FINISH_DATE_END;
import static org.jsola.contract.example.ContractExample.N_SIGN_FINISH_DATE_START;
import static org.jsola.contract.example.ContractExample.N_SIGN_NO;
import static org.jsola.contract.example.ContractExample.N_STATUS;
import static org.jsola.contract.example.ContractExample.N_SUBJECT_ID;
import static org.jsola.contract.example.ContractExample.N_TEMPLATE_ID;
import static org.jsola.core.example.BaseExample.M_ID_NOT_NULL;

/**
 * 合同
 *
 * @author JanusMix
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class ContractQuery extends BaseQuery {

    private static final long serialVersionUID = 1L;

    @ApiParam(value = N_CATEGORY_ID, example = E_CATEGORY_ID)
    private Long categoryId;

    @ApiParam(value = N_TEMPLATE_ID, example = E_TEMPLATE_ID)
    private Long templateId;

    @ApiParam(value = N_CONTRACT_NO, example = E_CONTRACT_NO)
    @Length(max = 255)
    private String contractNo;

    @ApiParam(value = N_SIGN_NO, example = E_SIGN_NO)
    @Length(max = 20)
    private String signNo;

    @ApiParam(value = N_SUBJECT_ID, example = E_SUBJECT_ID, required = true)
//    @NotNull(message = "请传递合同所属业务Id,例如:公司id")
    private String subjectId;

    @ApiParam(value = "subjectIds", example = "[\"asdsad\", \"asdasd\",...]")
    private List<String> subjectIds;

    @ApiParam(value = "合同idList")
    private List<String> contractIdList;


    @ApiParam(value = N_NAME, example = E_NAME)
    @Length(max = 255)
    private String name;

    @ApiParam(value = N_SEAL_TYPE, example = E_SEAL_TYPE, allowableValues = SealType.VALUES_STR)
    @Length(max = 255)
    private String sealType;

    @ApiParam(value = N_CONTRACT_TYPE, example = E_CONTRACT_TYPE, allowableValues = ContractType.VALUES_STR)
    private Integer contractType;

    @ApiParam("是否筛选即将到期的合同")
    private Boolean willExpire;

    @ApiParam("是否筛选已经到期的合同")
    private Boolean alreadyExpire;

    @ApiParam("是否已查看")
    private Boolean isView;

    @ApiParam("成员Ids(乙方)")
    private List<String> memberIds;

    /**
     * 合同开始日期查询范围
     */
    @ApiParam(value = N_PUBLISH_DATE_START, example = E_PUBLISH_DATE_START)
    private Date publishDateStart;
    @ApiParam(value = N_PUBLISH_DATE_END, example = E_PUBLISH_DATE_END)
    private Date publishDateEnd;


    /**
     * 签订日期查询范围
     */
    @ApiParam(value = N_SIGN_DATE_START, example = E_SIGN_DATE_START)
    private Date signDateStart;
    @ApiParam(value = N_SIGN_DATE_END, example = E_SIGN_DATE_END)
    private Date signDateEnd;


    /**
     * 合同终止日期查询范围
     */
    @ApiParam(value = N_END_DATE_START, example = E_END_DATE_START)
    private Date endDateStart;
    @ApiParam(value = N_END_DATE_END, example = E_END_DATE_END)
    private Date endDateEnd;


    /**
     * 员工签署时间查询范围
     */
    @ApiParam(value = N_EMP_SIGN_DATE_START, example = E_EMP_SIGN_DATE_START)
    private Date empSignDateStart;
    @ApiParam(value = N_EMP_SIGN_DATE_END, example = E_EMP_SIGN_DATE_END)
    private Date empSignDateEnd;


    /**
     * 合同签署完成时间查询范围
     */
    @ApiParam(value = N_SIGN_FINISH_DATE_START, example = E_SIGN_FINISH_DATE_START)
    private Date signFinishDateStart;
    @ApiParam(value = N_SIGN_FINISH_DATE_END, example = E_SIGN_FINISH_DATE_END)
    private Date signFinishDateEnd;


    @ApiParam(value = N_PARTY_A_ACCOUNT_ID, example = E_PARTY_A_ACCOUNT_ID)
    @Length(max = 40)
    private String partyAAccountId;

    @ApiParam(value = N_PARTY_A_NAME, example = E_PARTY_A_NAME)
    @Length(max = 2147483647)
    private String partyAName;

    @ApiParam(value = N_PARTY_B_ACCOUNT_ID, example = E_PARTY_B_ACCOUNT_ID)
    @Length(max = 40)
    private String partyBAccountId;

    @ApiParam(value = "签署乙方账户id列表")
    private List<String> partyBAccountIds;

    @ApiParam(value = N_PARTY_B_NAME, example = E_PARTY_B_NAME)
    @Length(max = 2147483647)
    private String partyBName;

    @ApiParam(value = N_PRICE, example = E_PRICE)
    private Long price;

    @ApiParam(value = N_STATUS, example = E_STATUS)
    private Integer status;

    @ApiParam(value = N_DATELINE, example = E_DATELINE)
    private Integer dateline;

    @ApiParam(value = N_FILE_TYPE, example = E_FILE_TYPE, allowableValues = FileType.VALUES_STR)
    @Length(max = 50)
    private String fileType;

    @ApiParam(value = N_CONTENT, example = E_CONTENT)
    @Length(max = 2147483647)
    private String content;

    @ApiParam(value = N_NEED_INIT_AGAIN, example = E_NEED_INIT_AGAIN)
    private Boolean needInitAgain;

    @ApiParam(value = N_AGAIN_CONTRACT_ID, example = E_AGAIN_CONTRACT_ID)
    private Long againContractId;

    @ApiParam(value = N_APP_IS_SHOW, example = E_APP_IS_SHOW)
    private Boolean appIsShow;

    @ApiParam(value = N_IS_CHECK_FACE, example = E_IS_CHECK_FACE)
    private Boolean isCheckFace;


    @ApiParam(value = org.jsola.contract.example.CategoryExample.N_NAME, example = org.jsola.contract.example.CategoryExample.E_NAME)
    @Length(max = 255)
    private String contractCategoryName;

    @ApiParam(value = "手机号,例:'1585426'根据手机号模糊搜索")
    private String phone;

    @ApiParam(value = "多个手机号,例:'15854239876,15854239876'检索多个员工")
    private String phones;


    @ApiParam(value = "排序字段", allowMultiple = true, type = "Order", example = "\"orders\": [{\"property\": \"userName\",\"desc\": false}]")
    private List<Order> orders;

    /**
     * 每页的条数
     */
    @ApiParam(value = "分页参数，每页的条数", example = "20")
    @Max(value = 1000, message = "pageSize不能大于1000")
    private Integer pageSize = 20;

    /**
     * 当前第几页
     */
    @ApiParam(value = "分页参数，第几页", example = "1")
    @Min(value = 1, message = "pageNo不能小于1")
    private Integer pageNo = 1;


    /**
     * 添加排序
     *
     * @param propertyName 属性名
     * @param desc         是否降序
     * @return this
     */
    public ContractQuery addOrder(String propertyName, boolean desc) {
        if (CollectionUtils.isEmpty(this.orders)) {
            this.orders = new ArrayList<>();
        }
        this.orders.add(new Order(propertyName, desc));
        return this;
    }

    @ApiParam(value = "合同编号或名称或签署编号或员工手机号")
    private String contractNameOrNoOrSignNo;

    @ApiParam(value = "合同分组id")
    private String groupId;
}

